package com.xian.zk.core;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import com.xian.zk.model.Instance;
import com.xian.zk.model.ServerNode;
import lombok.extern.slf4j.Slf4j;

import java.time.Instant;
import java.util.*;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.stream.Collectors;

/**
 * @program: zoo-task
 * @description:
 * @author: liru.xian
 * @create: 2022-01-14 17:12
 **/
@Slf4j
public class DataServerUtil {

    private static Multimap<String, Instance> SERVER_NODE_CONTEXT = ArrayListMultimap.create();
    public static final ObjectMapper mapper = new ObjectMapper();

    private static final ReentrantReadWriteLock reentrant_lock = new ReentrantReadWriteLock(true);
    private static final ReentrantReadWriteLock.WriteLock  writeLock = reentrant_lock.writeLock();
    private static final ReentrantReadWriteLock.ReadLock  readLock = reentrant_lock.readLock();


    /**
     * 添加
     * @param serverName
     * @param serverNode
     * @return
     */
    public static Boolean add(String serverName,Instance serverNode){
        writeLock.lock();
        try {
            SERVER_NODE_CONTEXT.put(serverName, serverNode);
            return Boolean.TRUE;
        }finally {
            writeLock.unlock();
        }
    }

    /**
     * 更新
     *
     * @param serverName
     * @param serverNode
     * @return
     */
    public static Boolean update(String serverName, Instance serverNode) {
        writeLock.lock();
        try {
            SERVER_NODE_CONTEXT.remove(serverName,serverNode);
            SERVER_NODE_CONTEXT.put(serverName,serverNode);
            return Boolean.TRUE;
        }finally {
            writeLock.unlock();
        }
    }

    /**
     * 删除节点
     *
     * @param serverName
     * @return
     */
    public static Boolean remove(String serverName,String instanceId) {
        writeLock.lock();
        try {
            ServerNode tager = null;
            Collection<Instance> instances = SERVER_NODE_CONTEXT.get(serverName);
            List<Instance> nodes = instances.stream().filter(node -> node.getInstanceId().equals(instanceId))
                    .collect(Collectors.toList());
            if(!nodes.isEmpty()){
                SERVER_NODE_CONTEXT.remove(serverName,nodes.get(0));
            }
            return Boolean.TRUE;
        }finally {
            writeLock.unlock();
        }
    }

    /**
     * 获取所有节点
     *
     * @return
     */
    public static List<Instance> getInstancesByServiceName(String serverName) {
        readLock.lock();
        try {
            Collection<Instance> Instances = SERVER_NODE_CONTEXT.get(serverName);
            return new ArrayList<>(Instances);
        }finally {
            readLock.unlock();
        }
    }

    /**
     * 获取所有节点
     *
     * @return
     */
    public static Instance getInstancesByInstanceId(String instanceId) {
        List<Instance> ins = new ArrayList<>();
        readLock.lock();
        try {

            Set<String> set = SERVER_NODE_CONTEXT.keySet();
            set.forEach( serviceName -> {
                Collection<Instance> instances = SERVER_NODE_CONTEXT.get(serviceName);
                instances.forEach( instance -> {
                    if(instance.getInstanceId().equals(instanceId)){
                        ins.add(instance);
                    }
                });
            });
        }finally {
            readLock.unlock();
        }
        return ins.get(0);
    }
}
